package leetcode.digui_huisu;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * 77. 组合
 * <p>
 * 给定两个整数 n 和 k，返回 1 ... n 中所有可能的 k 个数的组合。
 * <p>
 * 示例:
 * <p>
 * 输入: n = 4, k = 2
 * 输出:
 * [
 * [2,4],
 * [3,4],
 * [2,3],
 * [1,2],
 * [1,3],
 * [1,4],
 * ]
 * 回溯法
 */
public class Solution77 {
    private List<List<Integer>> res;

    public List<List<Integer>> combine(int n, int k) {
        if (n < 0 || k < 0 || k > n) {
            return Collections.emptyList();
        }
        LinkedList<Integer> c = new LinkedList<>();
        res = new ArrayList<>();
        combine(n, k, 1, c);
        return res;
    }

    /**
     * 元素不能重复使用
     * C(n,k)
     *
     * @param n     n
     * @param k     k
     * @param start 从start位置开始搜索新值存放到 c
     */
    public void combine(int n, int k, int start, LinkedList<Integer> c) {
        //递归终止条件c.size() == k 已经存放够k个元素，进行保存，然后返回
        if (c.size() == k) {
            res.add((LinkedList<Integer>) c.clone());
            return;
        }

        for (int i = start; i <= n; i++) {//在start-n之间去组合k个元素 放到c中
            c.addLast(i);
            combine(n, k, i + 1, c);//在 i+1 中去组合
            c.removeLast();
        }
    }
}
